package com.example.lzh.component;

import com.example.lzh.model.DocInfo;
import com.example.lzh.model.Weight;
import org.ansj.domain.Term;
import org.ansj.splitWord.analysis.ToAnalysis;
import org.springframework.stereotype.Component;

import java.io.*;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Question Parser
 * @Date 2023/1/26 13:54
 * @Solution
 */
@Component
public class Parser {
    //指定文档路径
    private static final String INPUT_PATH="D:/WorkSpace/WebProject/搜索引擎/UR-Search/src/main/resources/static/docs/api";

    Index index = new Index();


    //单线程制作索引
    public void run() {
        //1.根据上述路径枚举出所有html
        long beg1=System.currentTimeMillis();
        ArrayList<File> fileList=new ArrayList<>();
        enumFile(INPUT_PATH,fileList);
        long end1=System.currentTimeMillis();
        //2.针对上面罗列出的文件的路径，打开文件，读取内容并解析，构建索引
        long beg=System.currentTimeMillis();
        System.out.println("开始解析HTML...");
        for(File file:fileList) {
            //解析单个HTML
            System.out.println("开始解析:"+file.getAbsolutePath());
            parseHTML(file);
        }
        long end=System.currentTimeMillis();
        System.out.println("枚举html 耗时："+(end1-beg1)+"毫秒");
        System.out.println("解析完成 耗时:"+(end-beg)+"毫秒");
        //3.将内存中的索引数据保存到指定的文件中
        index.save();
    }

    //多线程制作索引
    public void runByThread() throws InterruptedException {
        //1.根据上述路径枚举出所有html
        ArrayList<File> fileList=new ArrayList<>();
        enumFile(INPUT_PATH,fileList);
        //2.解析HTML
        long beg=System.currentTimeMillis();
        System.out.println("开始解析HTML...");
        CountDownLatch latch = new CountDownLatch(fileList.size());
        ExecutorService executorService = Executors.newFixedThreadPool(4);
        for(File file:fileList) {
            //解析单个HTML
            executorService.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("开始解析:"+file.getAbsolutePath());
                    parseHTML(file);
                    latch.countDown();
                }
            });
        }
        //等待线程池任务完成
        latch.await();
        long end=System.currentTimeMillis();
        System.out.println("解析完成 耗时:"+(end-beg)+"毫秒");
        //3.将内存中的索引数据保存到指定的文件中
        index.save();
        System.out.println("索引文件保存完毕");
        executorService.shutdown();
    }

    private void parseHTML(File file) {
        //解析标题
        String title=parseTitle(file);
        //解析URL
        String url=parseURL(file);
        //解析正文
        String content=parseContentByRegex(file);
        //加入到索引
        index.addDoc(title,url,content);
    }

    private String parseTitle(File file) {
        String fileName=file.getName();
        String title=fileName.substring(0,fileName.length()-5);
        return title;
    }

    private String parseURL(File file) {
        String pa="D:/WorkSpace/WebProject/搜索引擎/UR-Search/src/main/resources/static/docs/api/";
        //固定前缀
        String pre="https://docs.oracle.com/javase/8/docs/api/";
        String absolutePath = file.getAbsolutePath();
        String res=pre+absolutePath.substring(pa.length()).replaceAll("\\\\","/");
        return res;
    }

    private String readFile(File file) {
        try(BufferedReader bufferedReader = new BufferedReader(new FileReader(file),1024*1024)) {
            StringBuilder content=new StringBuilder();
            while(true) {
                int ret = bufferedReader.read();
                //如果ret==-1则为文件末尾，则终止
                if(ret==-1) {
                    break;
                }
                char c=(char)ret;
                if(c=='\n' ||c=='\r') {
                    c=' ';
                }
                content.append(c);
            }
            return content.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }
    private String parseContentByRegex(File file) {
        String content=readFile(file);
        //替换掉script标签
        content=content.replaceAll("<script.*?>(.*?)</script>"," ");
        //替换掉普通html标签
        content=content.replaceAll("<.*?>"," ");
        //合并多个空格
        content=content.replaceAll("\\s+"," ");
        return content;
    }

    private String parseContent(File file) {
        try(BufferedReader bufferedReader = new BufferedReader(new FileReader(file),1024*1024)) {
            boolean isCopy=true;
            StringBuilder content=new StringBuilder();
            while(true) {
                int ret = bufferedReader.read();
                //如果ret==-1则为文件末尾，则终止
                if(ret==-1) {
                    break;
                }
                char c=(char)ret;
                if(isCopy) {
                    if(c=='<') {
                        isCopy=false;
                        continue;
                    }
                    if(c=='\n' ||c=='\r') {
                        c=' ';
                    }
                    content.append(c);
                } else {
                    if(c=='>') {
                        isCopy=true;
                    }
                }
            }
            return content.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private void enumFile(String path,ArrayList<File> fileList) {
        File rootPath=new File(path);
        //listFiles能获取到当前目录下的目录和文件
        File[] files = rootPath.listFiles();
        for(File file:files) {
            if(file.isDirectory()) {
                enumFile(path+"/"+file.getName(),fileList);
            } else {
                //排除非HTML
                if(file.getName().endsWith(".html")) {
                    fileList.add(file);
                }
            }
        }
    }
}
